package com.cloud.pole.shop.service.order.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.cloud.pole.common.constant.CommonConstants;
import com.cloud.pole.common.exception.BaseException;
import com.cloud.pole.common.util.DateUtils;
import com.cloud.pole.common.util.ListUtils;
import com.cloud.pole.common.util.jwt.IJWTInfo;
import com.cloud.pole.common.util.jwt.JwtTokenUtil;
import com.cloud.pole.shop.biz.goods.ShopGoodsBiz;
import com.cloud.pole.shop.biz.order.ShopOrderBiz;
import com.cloud.pole.shop.biz.order.ShopOrderItemsBiz;
import com.cloud.pole.shop.biz.order.ShopOrderRefundBiz;
import com.cloud.pole.shop.biz.order.ShopOrderRefundDetailBiz;
import com.cloud.pole.shop.biz.order.ShopOrderRefundImageBiz;
import com.cloud.pole.shop.biz.shops.ShopShopsBiz;
import com.cloud.pole.shop.constant.ShopCommonConstant;
import com.cloud.pole.shop.model.entity.order.ShopOrder;
import com.cloud.pole.shop.model.entity.order.ShopOrderItems;
import com.cloud.pole.shop.model.entity.order.ShopOrderRefund;
import com.cloud.pole.shop.model.entity.order.ShopOrderRefundDetail;
import com.cloud.pole.shop.model.entity.order.ShopOrderRefundImage;
import com.cloud.pole.shop.model.vo.order.ShopOrderRefundAdminVo;
import com.cloud.pole.shop.model.vo.order.ShopOrderRefundVo;
import com.cloud.pole.shop.service.order.OrderRefundService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

/*
*2019年3月28日
*cloud-shop
*author:frank-chen
*/
@Service
@Slf4j
public class OrderRefundServiceImpl implements OrderRefundService {
	
	@Autowired
	private ShopOrderRefundBiz shopOrderRefundBiz;
	@Autowired 
	private ShopShopsBiz shopShopsBiz;
	@Autowired 
	private ShopOrderBiz shopOrderBiz;
	@Autowired 
	private ShopOrderItemsBiz shopOrderItemsBiz;
	@Autowired 
	private ShopGoodsBiz shopGoodsBiz;	
	@Autowired 
	private ShopOrderRefundDetailBiz shopOrderRefundDetailBiz;
	@Autowired 
	private ShopOrderRefundImageBiz shopOrderRefundImageBiz;
	
	@Override
	public Long addOrderRefund(String token, Long orderItemId, Integer refundWay, Integer refundGoodsStatus,
			String refundReason, String refundNote, String reasonImages, Integer refundAmount, String userMobile)
			throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jwtInfo = JwtTokenUtil.getInfoFromToken(token);
		Long userId = Long.parseLong(jwtInfo.getId());

		//验证参数是否正确
		ShopOrderItems  orderItems = shopOrderItemsBiz.selectByPrimaryKey(orderItemId);
		if(orderItems == null) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "orderItemId错误");
		}
		ShopOrder order = shopOrderBiz.selectByPrimaryKey(orderItems.getOrderSn());
		if(order == null || order.getUserId().longValue() != userId.longValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "订单错误");
		}
		/**
		 * 需要判断哪些需要退款、哪些需要退款退货
		 */
		if((order.getOrderStatus() != ShopOrder.ORDER_STATUS_PAY_OK && order.getOrderStatus() != ShopOrder.ORDER_STATUS_DELIVERED && order.getOrderStatus() != ShopOrder.ORDER_STATUS_FINISH ) || 
			order.getPayStatus() != ShopOrder.PAY_STATUS_YES ) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "已支付订单才能申请退款");
		}
		//订单完成15天内才能退款
		if(order.getAcceptTime() != null) {
			Long days = DateUtils.minusDay(order.getAcceptTime(), new Date(), true);
			if(days > ShopCommonConstant.SHOP_ORDER_REFUND_MAX_DAYS) {
				throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "已过订单退款时间");
			}
		}
		/**
		 * 判断是否已经退款
		 */
		if(orderItems.getRefundState() != ShopOrderItems.REFUND_STATE_NO) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "已经申请过退款");
		}
		//退款金额限制
		if(orderItems.getTotalPrice().longValue() < refundAmount.intValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "退款金额超过产品支付金额");
		}
		/**
		 * 订单是否有退款退货的情况
		 */		
		ShopOrderRefund entity = new ShopOrderRefund();
		entity.setCheckStatus(ShopOrderRefund.CHECK_STATUS_DEFAULT);
		entity.setGoodsCount(orderItems.getProductNum());
		entity.setGoodsId(orderItems.getGoodsId());
		entity.setGoodsSpecId(orderItems.getGoodsSpecId());
		entity.setOrderItemId(orderItems.getOrderItemId());
		entity.setOrderSn(orderItems.getOrderSn());
		entity.setRefundGoodsStatus(refundGoodsStatus);
		entity.setRefundNote(refundNote);
		entity.setRefundReason(refundReason);
		entity.setRefundStatus(ShopOrderRefund.REFUND_STATUS_BUYER_APPLIED);
		entity.setCreateTime(new Date());
		entity.setRefundType(ShopOrderRefund.REFUND_TYPE_BUYER);
		entity.setRefundWay(refundWay);
		entity.setShopId(orderItems.getShopId());
		entity.setShopName(orderItems.getShopName());
		entity.setUserApplyAmount(refundAmount);
		entity.setUserId(userId);
		entity.setUserMobile(userMobile);
		entity.setUserName(jwtInfo.getUniqueName());
		entity.setGoodsName(orderItems.getGoodsName());
		entity.setGoodsTitleImage(orderItems.getTitleImage());
		entity.setGoodsSpecName(orderItems.getGoodsSpecName());
		entity.setGoodsTitle(orderItems.getTitle());
		entity.setGoodsSimpleTitle(orderItems.getSimpleTitle());
		entity.setMerchantId(orderItems.getMerchantId());
		shopOrderRefundBiz.insertUseGeneratedKeys(entity);
		
		String[] imsges =  reasonImages.split(",");
		for(String imsge : imsges) {
			if(!StringUtils.isEmpty(imsge)) {
				ShopOrderRefundImage msg = new ShopOrderRefundImage();
				msg.setImageUrl(imsge);
				msg.setRefundId(entity.getRefundId());
				shopOrderRefundImageBiz.insertSelective(msg);
			}
		}
		
		//写入日志
		String title ="发起了退款申请，等待商家处理";
		StringBuffer content = new StringBuffer();
		content.append("退款方式：" + this.getRefundWayStr(refundWay) + "，" );
		content.append("货物状态：" + this.getRefundGoodsStatusStr(refundGoodsStatus) + "，" );
		content.append("退款金额：¥"+  (refundAmount / 100 )+ "，");
		content.append("退货数量：" + orderItems.getProductNum() + "，" );
		content.append("手机号码：" + userMobile + "， ");
		content.append("退款原因：" + refundReason + "， ");
		content.append("退款说明："+ refundNote + "。");
		ShopOrderRefundDetail detail = new ShopOrderRefundDetail();
		detail.setContent(content.toString());
		detail.setTitle(title);
		detail.setCreateTime(new Date());
		detail.setRefundId(entity.getRefundId());
		detail.setUserType(ShopOrderRefundDetail.USER_TYPE_BUYER);
		shopOrderRefundDetailBiz.insertSelective(detail);
		
		//更新订单item
		orderItems.setRefundState(ShopOrderItems.REFUND_STATE_ALL_REFUND_ING);
		shopOrderItemsBiz.updateSelectiveById(orderItems);
		return entity.getRefundId();
	}

	@Override
	public boolean cancelOrderRefund(String token, Long refundId) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jwtInfo = JwtTokenUtil.getInfoFromToken(token);
		Long userId = Long.parseLong(jwtInfo.getId());
		ShopOrderRefund orderRefund  = shopOrderRefundBiz.selectByPrimaryKey(refundId);
		if(orderRefund == null || orderRefund.getUserId().longValue() != userId.longValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "refundId错误");
		}
		/**
		 * 买家已经申请退款，等待卖家同意下可以取消退款
		 * 
		 */
		if(orderRefund.getRefundStatus() != ShopOrderRefund.REFUND_STATUS_BUYER_APPLIED) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "退款不能被取消");
		}
		//验证参数是否正确
		ShopOrderItems  orderItems = shopOrderItemsBiz.selectByPrimaryKey(orderRefund.getOrderItemId());
		if(orderItems == null) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "orderItemId错误");
		}
		orderRefund.setCloseTime(new Date());
		orderRefund.setRefundStatus(ShopOrderRefund.REFUND_STATUS_CLOSE);
		shopOrderRefundBiz.updateSelectiveById(orderRefund);

		//更新订单item
		orderItems.setRefundState(ShopOrderItems.REFUND_STATE_NO);
		shopOrderItemsBiz.updateSelectiveById(orderItems);
				
		//写入日志
		String title ="撤销退款申请，退款关闭";
		ShopOrderRefundDetail detail = new ShopOrderRefundDetail();
		detail.setCreateTime(new Date());
		detail.setTitle(title);
		detail.setRefundId(orderRefund.getRefundId());
		detail.setUserType(ShopOrderRefundDetail.USER_TYPE_BUYER);
		shopOrderRefundDetailBiz.insertSelective(detail);
				
		
		return true;
	}
	
	/**
	 * 方式:1：退货退款,2::仅退款
	 */
	@Override
	public String getRefundWayStr(int refundWay) throws Exception {
		// TODO Auto-generated method stub
		String strInfo = "";
		switch(refundWay) {
			case 1 :
				   strInfo = "退货退款";
				   break;
			case 2 :
				   strInfo = "退款";
				   break;
			default :
				   strInfo = "";		
				   break;
		}
		return strInfo;	
	}
	
	/**
	 * 退款状态（1:买家已经申请退款，等待卖家同意; 10:卖家拒绝退款; 20:卖家已经同意退货，等待买家退货; 30:买家已经退货，等待卖家确认收货; 40:卖家未收到货,拒绝退款; 50:退款关闭; 60:退款成功）
	 */
	@Override
	public String getRefundStatusStr(int refundStatus) throws Exception {
		// TODO Auto-generated method stub
		String strInfo = "";
		switch(refundStatus) {
			case 1 :
				   strInfo = "已申请";
				   break;
			case 10 :
				   strInfo = "拒绝";
				   break;
			case 20 :
				   strInfo = "已同意";
				   break;
			case 30 :
				   strInfo = "买家已退货";
				   break;
			case 40 :
				   strInfo = "未收到货";
				   break;
			case 50 :
				   strInfo = "退款关闭";
				   break;
			case 60 :
				   strInfo = "退款成功";
				   break;				   
			default :
				   strInfo = "";		
				   break;
		}
		return strInfo;	
	}
	
	/**
	 * 收货状态（1：未收到货 2：已收到货）
	 */
	@Override
	public String getRefundGoodsStatusStr(int refundGoodsStatus) throws Exception {
		// TODO Auto-generated method stub
		String strInfo = "";
		switch(refundGoodsStatus) {
			case 1 :
				   strInfo = "未收到货";
				   break;
			case 2 :
				   strInfo = "已收到货";
				   break;
			default :
				   strInfo = "";		
				   break;
		}
		return strInfo;	
	}

	@Override
	public PageInfo<ShopOrderRefundVo> getPageOrderRefundList(String token, Integer pageNum, Integer pageSize)
			throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jwtInfo = JwtTokenUtil.getInfoFromToken(token);
		Long userId = Long.parseLong(jwtInfo.getId());
		PageHelper.startPage(pageNum, pageSize); 
		List<ShopOrderRefund> list = shopOrderRefundBiz.selectOrderRefundListByUserId(userId);
		List<ShopOrderRefundVo> listVo = ListUtils.copyListProperties(list, ShopOrderRefundVo.class);
		for(ShopOrderRefundVo msg : listVo) {
			msg.setRefundWayStr(getRefundWayStr(msg.getRefundWay()));
			msg.setRefundStatusStr(getRefundStatusStr(msg.getRefundStatus()));
			msg.setRefundGoodsStatusStr(getRefundGoodsStatusStr(msg.getRefundGoodsStatus()));
		}
    	PageInfo<ShopOrderRefundVo> pageInfo = new PageInfo<ShopOrderRefundVo>(listVo);
		return pageInfo;
	}

	@Override
	public ShopOrderRefundVo getOrderRefund(String token, Long refundId) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jwtInfo = JwtTokenUtil.getInfoFromToken(token);
		Long userId = Long.parseLong(jwtInfo.getId());
		ShopOrderRefund orderRefund  = shopOrderRefundBiz.selectByPrimaryKey(refundId);
		if(orderRefund == null || orderRefund.getUserId().longValue() != userId.longValue()) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "refundId错误");
		}
		ShopOrderRefund shopOrderRefund = shopOrderRefundBiz.selectByPrimaryKey(refundId);
		ShopOrderRefundVo shopOrderRefundVo = ListUtils.entityToModel(shopOrderRefund, ShopOrderRefundVo.class);
		shopOrderRefundVo.setRefundWayStr(getRefundWayStr(shopOrderRefundVo.getRefundWay()));
		shopOrderRefundVo.setRefundStatusStr(getRefundStatusStr(shopOrderRefundVo.getRefundStatus()));
		shopOrderRefundVo.setRefundGoodsStatusStr(getRefundGoodsStatusStr(shopOrderRefundVo.getRefundGoodsStatus()));
		shopOrderRefundVo.setRefundDetailList(shopOrderRefundDetailBiz.selectOrderRefundDetailList(refundId));
		return shopOrderRefundVo;
	}

	@Override
	public PageInfo<ShopOrderRefundAdminVo> selectPageShopOrderRefundAdminList(Map<String, String> map, Integer pageNo,
			Integer pageSize) throws Exception {
		PageHelper.startPage(pageNo, pageSize); 
    	List<ShopOrderRefund> list = shopOrderRefundBiz.selectPageShopOrderRefundAdminList(map);
    	List<ShopOrderRefundAdminVo> listVo = ListUtils.copyListProperties(list, ShopOrderRefundAdminVo.class);
    	for(ShopOrderRefundAdminVo vo : listVo) {
    		vo.setRefundWayName(getRefundWayStr(vo.getRefundWay()));
    		vo.setRefundStatusName(getRefundStatusStr(vo.getRefundStatus()));
    		vo.setRefundGoodsStatusName(getRefundGoodsStatusStr(vo.getRefundGoodsStatus()));
		}
    	PageInfo<ShopOrderRefundAdminVo> page = new PageInfo<ShopOrderRefundAdminVo>(listVo);
    	return page;
	}

	@Override
	public ShopOrderRefundAdminVo selectOrderRefundAdminById(String refundId) throws Exception {
		ShopOrderRefund orderRefund  = shopOrderRefundBiz.selectByPrimaryKey(Long.parseLong(refundId));
		if(orderRefund == null) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "refundId错误");
		}
		ShopOrderRefundAdminVo shopOrderRefundAdminVo = ListUtils.entityToModel(orderRefund, ShopOrderRefundAdminVo.class);
		shopOrderRefundAdminVo.setRefundWayName(getRefundWayStr(shopOrderRefundAdminVo.getRefundWay()));
		shopOrderRefundAdminVo.setRefundStatusName(getRefundStatusStr(shopOrderRefundAdminVo.getRefundStatus()));
		shopOrderRefundAdminVo.setRefundGoodsStatusName(getRefundGoodsStatusStr(shopOrderRefundAdminVo.getRefundGoodsStatus()));
		shopOrderRefundAdminVo.setRefundDetailList(shopOrderRefundDetailBiz.selectOrderRefundDetailList(Long.parseLong(refundId)));
		shopOrderRefundAdminVo.setRefundImgList(shopOrderRefundImageBiz.selectOrderRefundImageList(Long.parseLong(refundId)));
		return shopOrderRefundAdminVo;
	}
}
